package com.cmj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmj.Utils.BeanCopyUtils;
import com.cmj.dao.ArticleMapper;
import com.cmj.dao.CategoryMapper;
import com.cmj.domain.ResponseResult;
import com.cmj.domain.SystemConstants;
import com.cmj.domain.dto.ArticleDto;
import com.cmj.domain.entity.Article;
import com.cmj.domain.vo.ArticleListVo;
import com.cmj.domain.vo.HotArticleVo;
import com.cmj.domain.vo.PageVo;
import com.cmj.service.ArticleService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;

import static com.cmj.domain.SystemConstants.ARTICLE_STATUS_NORMAL;
import static org.springframework.util.ObjectUtils.isEmpty;

/**
 * 文章表(Article)表服务实现类
 *
 * @author makejava
 * @since 2022-03-12 16:41:50
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper,Article> implements ArticleService {

    @Autowired
    ArticleMapper articleMapper;
    @Autowired
    CategoryMapper categoryMapper;
    @Autowired
    RedisTemplate redisTemplate;

    /***
     * 查询热门文章实现服务类
     * @return 查询到的热门文章
     */
    @Override
    public ResponseResult<Article> hotArticleList() {
        //查询正常发布的文章（status=0) 按浏览量降序排列 取前10条
        List<Article> articles = articleMapper.selHotArticleList(ARTICLE_STATUS_NORMAL);
        //复制到hotArticleVo中
        List<HotArticleVo> hotArticleVos = BeanCopyUtils.copyBeanList(articles, HotArticleVo.class);
        return ResponseResult.okResult(hotArticleVos);
    }

    /***
     * 获取文章列表
     * @param pageNum 页数
     * @param pageSize 每页大小
     * @param categoryId 文章id
     * @return 全部或分类的文章列表
     */
    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        //开启分页
        PageHelper.startPage(pageNum,pageSize);
        //查询已经发布（status=0) 置顶显示在前面（isTop排序） 有categoryId 就要 查询时要和传入的相同
        List<Article> articleList = articleMapper.selArticleList(categoryId,ARTICLE_STATUS_NORMAL);
        //查询分类名
        if(articleList != null || categoryId > 0){
            for (Article article : articleList) {
                article.setCategoryName(categoryMapper.selCategoryName(article.getCategoryId()));
            }
        }
        //复制到vo类中
        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(articleList, ArticleListVo.class);
        PageVo pageVo = new PageVo(articleListVos, new PageInfo(articleList).getTotal());
        return ResponseResult.okResult(pageVo);
    }

    /***
     * 文章详情
     * @param id 文章id
     * @return 文章详情
     */
    @Override
    public ResponseResult getArticleDetail(Long id) {
        //获取文章详情
        Article article = articleMapper.selArticleById(id);
        //设置分类名
        article.setCategoryName(categoryMapper.selCategoryName(article.getCategoryId()));
        //从redis获取浏览量
        Integer view = (Integer) redisTemplate.opsForHash().get("article:viewCount", id.toString());
        article.setViewCount(view.longValue());
        //返回结果
        return ResponseResult.okResult(article);
    }

    /**
     * 把浏览量更新到redis中
     * @param id 文章id
     * @return 操作结果
     */
    @Override
    public ResponseResult updateViewCount(Long id) {
        //更新浏览量到redis中 每点击一次执行
        redisTemplate.opsForHash().increment("article:viewCount",id.toString(),1l);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, ArticleDto articleDto) {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(articleDto.getTitle()),Article::getTitle,articleDto.getTitle());
        wrapper.like(StringUtils.hasText(articleDto.getSummary()),Article::getSummary,articleDto.getSummary());

        Page<Article> articlePage = new Page<>();
        articlePage.setCurrent(pageNum);
        articlePage.setSize(pageSize);
        page(articlePage,wrapper);

        PageVo pageVo = new PageVo(articlePage.getRecords(), articlePage.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult delArticle(Long[] id) {
        int i = articleMapper.deleteBatchIds(Arrays.asList(id));
        if (i == 0){
            new RuntimeException(SystemConstants.DELETE_FAIL);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<ArticleListVo> getArticle(Long id) {
        Article article = articleMapper.selectById(id);
        if (isEmpty(article)){
            new RuntimeException(SystemConstants.SELECT_FAIL);
        }
        ArticleListVo articleListVo = BeanCopyUtils.copyBean(article, ArticleListVo.class);
        return ResponseResult.okResult(articleListVo);
    }

    @Override
    public ResponseResult updateArticle(Article article) {
        QueryWrapper<Article> linkQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Article> id = linkQueryWrapper.eq("id", article.getId());
        int result = articleMapper.update(article, id);
        if (result == 0){
            new RuntimeException(SystemConstants.UPDATE_FAIL);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<ArticleListVo> addArticle(Article article) {
        int result = articleMapper.insert(article);
        if (result == 0){
            new RuntimeException(SystemConstants.INSERT_FAIL);
        }
        return ResponseResult.okResult();
    }
}
